#include "flash_api.h"
#include "memory_board.h"
#include "device_parameter.h"

/**
 * @brief 获取日志文件属性
 *
 * @param pAttributeOut - 日志属性
 */
// static void GetLogFileAttribute(LogFileAttribute_t *pAttributeOut);

/**
 * @brief 更新日志文件属性
 *
 * @param pAttributeIn - 日志属性
 */
// static void UpdateLogFileAttribute(LogFileAttribute_t *pAttributeIn);

/**
 * @brief 获取对应编码的日志表
 *
 * @param SheetTableId     - 日志表编码
 * @param pLogDataSheetOut - 日志表信息
 */
static void GetTheLogTableForTheCorrespondingCode(uint16_t SheetTableId, LogDataSheet_t *pLogDataSheetOut);

/**
 * @brief 更新对应编码的日志表
 *
 * @param SheetTableId    - 日志表编码
 * @param pLogDataSheetIn - 日志表信息
 */
static void UpdateTheLogTableForTheCorrespondingCode(uint16_t SheetTableId, LogDataSheet_t *pLogDataSheetIn);

/**
 * @brief 新增日志表
 *
 * @param pNewLogIn - 日志表
 * @return uint16_t - 写入表编码
 */
// static uint16_t NewLogTable(LogDataSheet_t *pNewLogIn);

// static void GetLogFileAttribute(LogFileAttribute_t *pAttributeOut)
// {
//   if (pAttributeOut != NULL)
//   {
//     FlashReadLogFile(0, pAttributeOut, sizeof(LogFileAttribute_t));
//   }
// }

static void UpdateLogFileAttribute(LogFileAttribute_t *pAttributeIn)
{
  // if (pAttributeIn != NULL)
  // {
  //   FlashWriteLogFile(0, pAttributeIn, sizeof(LogFileAttribute_t));
  // }
}

static void GetTheLogTableForTheCorrespondingCode(uint16_t SheetTableId, LogDataSheet_t *pLogDataSheetOut)
{
  // if (pLogDataSheetOut != NULL)
  // {
  //   if (SheetTableId < LOG_LIMIT)
  //   {
  //     uint32_t AddressOffset = (SheetTableId * sizeof(LogDataSheet_t)) + sizeof(LogFileAttribute_t);
  //     FlashReadLogFile(AddressOffset, pLogDataSheetOut, sizeof(LogDataSheet_t));
  //   }
  // }
}

static void UpdateTheLogTableForTheCorrespondingCode(uint16_t SheetTableId, LogDataSheet_t *pLogDataSheetIn)
{
  // uint32_t AddressOffset = (SheetTableId * sizeof(LogDataSheet_t)) + sizeof(LogFileAttribute_t);
  // FlashWriteLogFile(AddressOffset, pLogDataSheetIn, sizeof(LogDataSheet_t));
}

static uint16_t NewLogTable(LogDataSheet_t *pNewLogIn)
{
  // LogFileAttribute_t LogFileAttribute = {0};

  // if (pNewLogIn != NULL)
  // {
  //   if ((GetDeviceInitStatus() & (~FIRMWARE_UPGRADE)) == NORMAL_MODE)
  //   {
  //     {
  //       GetLogFileAttribute(&LogFileAttribute);
  //       if (LogFileAttribute.WriteOffset >= LOG_LIMIT)
  //       {
  //         LogFileAttribute.WriteOffset = 0;
  //       }

  //       if (LogFileAttribute.Quantity > LOG_LIMIT)
  //       {
  //         LogFileAttribute.Quantity = 0;
  //       }
  //     }

  //     {
  //       UpdateTheLogTableForTheCorrespondingCode(LogFileAttribute.WriteOffset++, pNewLogIn);
  //       if (LogFileAttribute.Quantity < LOG_LIMIT)
  //       {
  //         LogFileAttribute.Quantity++;
  //       }

  //       MemoryMarkLogToBeUpload();
  //       UpdateLogFileAttribute(&LogFileAttribute);
  //     }
  //   }
  // }

  // return LogFileAttribute.WriteOffset;
}

uint16_t WritePhysicalCardNumberLog(const void *pCardNumberIn, const uint8_t NumberOfCard, const uint8_t Status)
{
   uint16_t WriteTableId = 0;
  // LogDataSheet_t PhysicalCardLogInfo = {0};
  // uint32_t NowTimestamp = MemoryGetTimestamp();

  // if ((pCardNumberIn != NULL) && (NumberOfCard <= LOG_DATA_PACKET_LENGTH))
  // {
  //   memset(&PhysicalCardLogInfo, 0, sizeof(LogDataSheet_t));

  //   PhysicalCardLogInfo.AttachParam = Status;
  //   PhysicalCardLogInfo.PushStatus = LOG_CACHE_TO_RETRIEVE;
  //   PhysicalCardLogInfo.EventType = LOG_PHYSICAL_CARD_NUMBER;
  //   PhysicalCardLogInfo.Time[0] = (uint8_t)((NowTimestamp & 0xFF000000) >> 24);
  //   PhysicalCardLogInfo.Time[1] = (uint8_t)((NowTimestamp & 0x00FF0000) >> 16);
  //   PhysicalCardLogInfo.Time[2] = (uint8_t)((NowTimestamp & 0x0000FF00) >> 8);
  //   PhysicalCardLogInfo.Time[3] = (uint8_t)(NowTimestamp & 0x000000FF);
  //   memcpy(PhysicalCardLogInfo.DataPacket, pCardNumberIn, NumberOfCard);
  //   WriteTableId = NewLogTable(&PhysicalCardLogInfo);
  // }

  return WriteTableId;
}

uint16_t WriteCalibrationCardNumberLog(const void *pCardNumberIn, const uint8_t NumberOfCard, const uint8_t Status)
{
  uint16_t WriteTableId = 0;
  LogDataSheet_t CalibrationCardLogInfo = {0};
  uint32_t NowTimestamp = MemoryGetTimestamp();

  if ((pCardNumberIn != NULL) && (NumberOfCard <= LOG_DATA_PACKET_LENGTH))
  {
    memset(&CalibrationCardLogInfo, 0, sizeof(LogDataSheet_t));

    CalibrationCardLogInfo.AttachParam = Status;
    CalibrationCardLogInfo.PushStatus = LOG_CACHE_TO_RETRIEVE;
    CalibrationCardLogInfo.EventType = LOG_CALIBRATION_TIME_CARD;
    CalibrationCardLogInfo.Time[0] = (uint8_t)((NowTimestamp & 0xFF000000) >> 24);
    CalibrationCardLogInfo.Time[1] = (uint8_t)((NowTimestamp & 0x00FF0000) >> 16);
    CalibrationCardLogInfo.Time[2] = (uint8_t)((NowTimestamp & 0x0000FF00) >> 18);
    CalibrationCardLogInfo.Time[3] = (uint8_t)(NowTimestamp & 0x000000FF);
    memcpy(CalibrationCardLogInfo.DataPacket, pCardNumberIn, NumberOfCard);
    WriteTableId = NewLogTable(&CalibrationCardLogInfo);
  }

  return WriteTableId;
}

uint16_t WriteGuestCardNumberLog(const void *pCardNumberIn, const uint8_t NumberOfCard, const uint8_t Status)
{
  uint16_t WriteTableId = 0;
  // LogDataSheet_t GuestCardLogInfo = {0};
  // uint32_t NowTimestamp = MemoryGetTimestamp();

  // if ((pCardNumberIn != NULL) && (NumberOfCard <= LOG_DATA_PACKET_LENGTH))
  // {
  //   memset(&GuestCardLogInfo, 0, sizeof(LogDataSheet_t));

  //   GuestCardLogInfo.AttachParam = Status;
  //   GuestCardLogInfo.EventType = LOG_GUEST_ROOM_CARD;
  //   GuestCardLogInfo.PushStatus = LOG_CACHE_TO_RETRIEVE;
  //   GuestCardLogInfo.Time[0] = (uint8_t)((NowTimestamp & 0xFF000000) >> 24);
  //   GuestCardLogInfo.Time[1] = (uint8_t)((NowTimestamp & 0x00FF0000) >> 16);
  //   GuestCardLogInfo.Time[2] = (uint8_t)((NowTimestamp & 0x0000FF00) >> 8);
  //   GuestCardLogInfo.Time[3] = (uint8_t)(NowTimestamp & 0x000000FF);
  //   memcpy(GuestCardLogInfo.DataPacket, pCardNumberIn, NumberOfCard);
  //   WriteTableId = NewLogTable(&GuestCardLogInfo);
  // }

  return WriteTableId;
}

uint16_t WriteMasterCardNumberLog(const void *pCardNumberIn, const uint8_t NumberOfCard, const uint8_t Status)
{
  uint16_t WriteTableId = 0;
  // LogDataSheet_t MasterCardLogInfo = {0};
  // uint32_t NowTimestamp = MemoryGetTimestamp();

  // if ((pCardNumberIn != NULL) && (NumberOfCard <= LOG_DATA_PACKET_LENGTH))
  // {
  //   memset(&MasterCardLogInfo, 0, sizeof(LogDataSheet_t));

  //   MasterCardLogInfo.AttachParam = Status;
  //   MasterCardLogInfo.EventType = LOG_MASTER_ROOM_CARD;
  //   MasterCardLogInfo.PushStatus = LOG_CACHE_TO_RETRIEVE;
  //   MasterCardLogInfo.Time[0] = (uint8_t)((NowTimestamp & 0xFF000000) >> 24);
  //   MasterCardLogInfo.Time[1] = (uint8_t)((NowTimestamp & 0x00FF0000) >> 16);
  //   MasterCardLogInfo.Time[2] = (uint8_t)((NowTimestamp & 0x0000FF00) >> 8);
  //   MasterCardLogInfo.Time[3] = (uint8_t)(NowTimestamp & 0x000000FF);
  //   memcpy(MasterCardLogInfo.DataPacket, pCardNumberIn, NumberOfCard);
  //   WriteTableId = NewLogTable(&MasterCardLogInfo);
  // }

  return WriteTableId;
}

uint16_t WriteBuildCardNumberLog(const void *pCardNumberIn, const uint8_t NumberOfCard, const uint8_t Status)
{
  uint16_t WriteTableId = 0;
  // LogDataSheet_t BuildCardLogInfo = {0};
  // uint32_t NowTimestamp = MemoryGetTimestamp();

  // if ((pCardNumberIn != NULL) && (NumberOfCard <= LOG_DATA_PACKET_LENGTH))
  // {
  //   memset(&BuildCardLogInfo, 0, sizeof(LogDataSheet_t));

  //   BuildCardLogInfo.AttachParam = Status;
  //   BuildCardLogInfo.EventType = LOG_BUILD_ROOM_CARD;
  //   BuildCardLogInfo.PushStatus = LOG_CACHE_TO_RETRIEVE;
  //   BuildCardLogInfo.Time[0] = (uint8_t)((NowTimestamp & 0xFF000000) >> 24);
  //   BuildCardLogInfo.Time[1] = (uint8_t)((NowTimestamp & 0x00FF0000) >> 16);
  //   BuildCardLogInfo.Time[2] = (uint8_t)((NowTimestamp & 0x0000FF00) >> 8);
  //   BuildCardLogInfo.Time[3] = (uint8_t)(NowTimestamp & 0x000000FF);
  //   memcpy(BuildCardLogInfo.DataPacket, pCardNumberIn, NumberOfCard);
  //   WriteTableId = NewLogTable(&BuildCardLogInfo);
  // }

  return WriteTableId;
}

uint16_t WriteFloorCardNumberLog(const void *pCardNumberIn, const uint8_t NumberOfCard, const uint8_t Status)
{
  uint16_t WriteTableId = 0;
  // LogDataSheet_t FloorCardLogInfo = {0};
  // uint32_t NowTimestamp = MemoryGetTimestamp();

  // if ((pCardNumberIn != NULL) && (NumberOfCard <= LOG_DATA_PACKET_LENGTH))
  // {
  //   memset(&FloorCardLogInfo, 0, sizeof(LogDataSheet_t));

  //   FloorCardLogInfo.AttachParam = Status;
  //   FloorCardLogInfo.EventType = LOG_FLOOR_ROOM_CARD;
  //   FloorCardLogInfo.PushStatus = LOG_CACHE_TO_RETRIEVE;
  //   FloorCardLogInfo.Time[0] = (uint8_t)((NowTimestamp & 0xFF000000) >> 24);
  //   FloorCardLogInfo.Time[1] = (uint8_t)((NowTimestamp & 0x00FF0000) >> 16);
  //   FloorCardLogInfo.Time[2] = (uint8_t)((NowTimestamp & 0x0000FF00) >> 8);
  //   FloorCardLogInfo.Time[3] = (uint8_t)(NowTimestamp & 0x000000FF);
  //   memcpy(FloorCardLogInfo.DataPacket, pCardNumberIn, NumberOfCard);
  //   WriteTableId = NewLogTable(&FloorCardLogInfo);
  // }

  return WriteTableId;
}

uint16_t WriteCleaningStaffCardNumberLog(const void *pCardNumberIn, const uint8_t NumberOfCard, const uint8_t Status)
{
  uint16_t WriteTableId = 0;
  uint32_t NowTimestamp = MemoryGetTimestamp();
  LogDataSheet_t CleaningStaffCardLogInfo = {0};

  if ((pCardNumberIn != NULL) && (NumberOfCard <= LOG_DATA_PACKET_LENGTH))
  {
    memset(&CleaningStaffCardLogInfo, 0, sizeof(LogDataSheet_t));

    CleaningStaffCardLogInfo.AttachParam = Status;
    CleaningStaffCardLogInfo.PushStatus = LOG_CACHE_TO_RETRIEVE;
    CleaningStaffCardLogInfo.EventType = LOG_CLEANING_STAFF_CARD;
    CleaningStaffCardLogInfo.Time[0] = (uint8_t)((NowTimestamp & 0xFF000000) >> 24);
    CleaningStaffCardLogInfo.Time[1] = (uint8_t)((NowTimestamp & 0x00FF0000) >> 16);
    CleaningStaffCardLogInfo.Time[2] = (uint8_t)((NowTimestamp & 0x0000FF00) >> 8);
    CleaningStaffCardLogInfo.Time[3] = (uint8_t)(NowTimestamp & 0x000000FF);
    memcpy(CleaningStaffCardLogInfo.DataPacket, pCardNumberIn, NumberOfCard);
    WriteTableId = NewLogTable(&CleaningStaffCardLogInfo);
  }

  return WriteTableId;
}

uint16_t WriteParkCardNumberLog(const void *pCardNumberIn, const uint8_t NumberOfCard, const uint8_t Status)
{
  uint16_t WriteTableId = 0;
  uint32_t NowTimestamp = MemoryGetTimestamp();
  LogDataSheet_t EmergencyDoorOpenCardLogInfo = {0};

  if ((pCardNumberIn != NULL) && (NumberOfCard <= LOG_DATA_PACKET_LENGTH))
  {
    memset(&EmergencyDoorOpenCardLogInfo, 0, sizeof(LogDataSheet_t));

    EmergencyDoorOpenCardLogInfo.AttachParam = Status;
    EmergencyDoorOpenCardLogInfo.EventType = LOG_PARK_ROOM_CARD;
    EmergencyDoorOpenCardLogInfo.PushStatus = LOG_CACHE_TO_RETRIEVE;
    EmergencyDoorOpenCardLogInfo.Time[0] = (uint8_t)((NowTimestamp & 0xFF000000) >> 24);
    EmergencyDoorOpenCardLogInfo.Time[1] = (uint8_t)((NowTimestamp & 0x00FF0000) >> 16);
    EmergencyDoorOpenCardLogInfo.Time[2] = (uint8_t)((NowTimestamp & 0x0000FF00) >> 8);
    EmergencyDoorOpenCardLogInfo.Time[3] = (uint8_t)(NowTimestamp & 0x000000FF);
    memcpy(EmergencyDoorOpenCardLogInfo.DataPacket, pCardNumberIn, NumberOfCard);
    WriteTableId = NewLogTable(&EmergencyDoorOpenCardLogInfo);
  }

  return WriteTableId;
}

uint16_t WriteClearTheKeyLog(const void *pCardNumberIn, const uint8_t NumberOfCard, const uint8_t Status)
{
  uint16_t WriteTableId = 0;
  LogDataSheet_t ClearTheKeyLogInfo = {0};
  uint32_t NowTimestamp = MemoryGetTimestamp();

  if ((pCardNumberIn != NULL) && (NumberOfCard <= LOG_DATA_PACKET_LENGTH))
  {
    memset(&ClearTheKeyLogInfo, 0, sizeof(LogDataSheet_t));

    ClearTheKeyLogInfo.AttachParam = Status;
    ClearTheKeyLogInfo.PushStatus = LOG_CACHE_TO_RETRIEVE;
    ClearTheKeyLogInfo.EventType = LOG_CLEAR_PARAMETER_CARD;
    ClearTheKeyLogInfo.Time[0] = (uint8_t)((NowTimestamp & 0xFF000000) >> 24);
    ClearTheKeyLogInfo.Time[1] = (uint8_t)((NowTimestamp & 0x00FF0000) >> 16);
    ClearTheKeyLogInfo.Time[2] = (uint8_t)((NowTimestamp & 0x0000FF00) >> 8);
    ClearTheKeyLogInfo.Time[3] = (uint8_t)(NowTimestamp & 0x000000FF);
    memcpy(ClearTheKeyLogInfo.DataPacket, pCardNumberIn, NumberOfCard);
    WriteTableId = NewLogTable(&ClearTheKeyLogInfo);
  }

  return WriteTableId;
}

uint16_t WriteBluetoothVirtualCardOpenDoorLog(const void *pCardNumberIn, const uint8_t NumberOfCard, const uint8_t Status)
{
  uint16_t WriteTableId = 0;
  uint32_t NowTimestamp = MemoryGetTimestamp();
  LogDataSheet_t BluetoothVirtualCardLogInfo = {0};

  if (pCardNumberIn != NULL)
  {
    if ((NumberOfCard > 0) && (NumberOfCard <= LOG_DATA_PACKET_LENGTH))
    {
      memset(&BluetoothVirtualCardLogInfo, 0, sizeof(LogDataSheet_t));

      BluetoothVirtualCardLogInfo.AttachParam = Status;
      BluetoothVirtualCardLogInfo.PushStatus = LOG_CACHE_TO_RETRIEVE;
      BluetoothVirtualCardLogInfo.EventType = LOG_BLUETOOTH_VIRTUAL_CARD_NUMBER;
      BluetoothVirtualCardLogInfo.Time[0] = (uint8_t)((NowTimestamp & 0xFF000000) >> 24);
      BluetoothVirtualCardLogInfo.Time[1] = (uint8_t)((NowTimestamp & 0x00FF0000) >> 16);
      BluetoothVirtualCardLogInfo.Time[2] = (uint8_t)((NowTimestamp & 0x0000FF00) >> 8);
      BluetoothVirtualCardLogInfo.Time[3] = (uint8_t)(NowTimestamp & 0x000000FF);
      memcpy(BluetoothVirtualCardLogInfo.DataPacket, pCardNumberIn, NumberOfCard);
      WriteTableId = NewLogTable(&BluetoothVirtualCardLogInfo);
    }
  }

  return WriteTableId;
}

uint16_t WriteKeyboardScanfLog(const void *pUserTokenIn, uint8_t NumberOfToken, const uint8_t Status)
{
  uint16_t WriteTableId = 0;
  LogDataSheet_t KeyboardScanfLogInfo = {0};
  uint32_t NowTimestamp = MemoryGetTimestamp();

  if (pUserTokenIn != NULL)
  {
    if ((NumberOfToken > 0) && (NumberOfToken <= LOG_DATA_PACKET_LENGTH))
    {
      memset(&KeyboardScanfLogInfo, 0, sizeof(LogDataSheet_t));

      KeyboardScanfLogInfo.AttachParam = Status;
      KeyboardScanfLogInfo.PushStatus = LOG_CACHE_TO_RETRIEVE;
      KeyboardScanfLogInfo.EventType = LOG_USER_KEYSCANF_PASSWORD;
      KeyboardScanfLogInfo.Time[0] = (uint8_t)((NowTimestamp & 0xFF000000) >> 24);
      KeyboardScanfLogInfo.Time[1] = (uint8_t)((NowTimestamp & 0x00FF0000) >> 16);
      KeyboardScanfLogInfo.Time[2] = (uint8_t)((NowTimestamp & 0x0000FF00) >> 8);
      KeyboardScanfLogInfo.Time[3] = (uint8_t)(NowTimestamp & 0x000000FF);
      memcpy(KeyboardScanfLogInfo.DataPacket, pUserTokenIn, NumberOfToken);
      WriteTableId = NewLogTable(&KeyboardScanfLogInfo);
    }
  }

  return WriteTableId;
}

uint16_t WriteQrcodeUnlockExecuteResultLog(const void *pDataIn, uint8_t DataSize, uint8_t Status)
{
  uint16_t WriteTableId = 0;
  LogDataSheet_t QrcodeScanfLogInfo = {0};
  uint32_t NowTimestamp = MemoryGetTimestamp();

  if (pDataIn != NULL)
  {
    if (DataSize != 0 && DataSize <= LOG_DATA_PACKET_LENGTH)
    {
      memset(&QrcodeScanfLogInfo, 0, sizeof(LogDataSheet_t));

      QrcodeScanfLogInfo.AttachParam = Status;
      QrcodeScanfLogInfo.EventType = LOG_QR_CODE_SCANF;
      QrcodeScanfLogInfo.PushStatus = LOG_CACHE_TO_RETRIEVE;
      QrcodeScanfLogInfo.Time[0] = (uint8_t)((NowTimestamp & 0xFF000000) >> 24);
      QrcodeScanfLogInfo.Time[1] = (uint8_t)((NowTimestamp & 0x00FF0000) >> 16);
      QrcodeScanfLogInfo.Time[2] = (uint8_t)((NowTimestamp & 0x0000FF00) >> 8);
      QrcodeScanfLogInfo.Time[3] = (uint8_t)(NowTimestamp & 0x000000FF);
      memcpy(QrcodeScanfLogInfo.DataPacket, pDataIn, DataSize);
      WriteTableId = NewLogTable(&QrcodeScanfLogInfo);
    }
  }

  return WriteTableId;
}

uint16_t WriteFingerprintVerificationLog(const void *pUserTokenIn, uint8_t NumberOfToken, const uint8_t Status)
{
  uint16_t WriteTableId = 0;
  uint32_t NowTimestamp = MemoryGetTimestamp();
  LogDataSheet_t FingerprintVerificationInfo = {0};

  if (pUserTokenIn != NULL)
  {
    if ((NumberOfToken > 0) && (NumberOfToken <= LOG_DATA_PACKET_LENGTH))
    {
      memset(&FingerprintVerificationInfo, 0, sizeof(LogDataSheet_t));

      FingerprintVerificationInfo.AttachParam = Status;
      FingerprintVerificationInfo.EventType = LOG_FINGER_SCANF;
      FingerprintVerificationInfo.PushStatus = LOG_CACHE_TO_RETRIEVE;
      FingerprintVerificationInfo.Time[0] = (uint8_t)((NowTimestamp & 0xFF000000) >> 24);
      FingerprintVerificationInfo.Time[1] = (uint8_t)((NowTimestamp & 0x00FF0000) >> 16);
      FingerprintVerificationInfo.Time[2] = (uint8_t)((NowTimestamp & 0x0000FF00) >> 8);
      FingerprintVerificationInfo.Time[3] = (uint8_t)(NowTimestamp & 0x000000FF);
      memcpy(FingerprintVerificationInfo.DataPacket, pUserTokenIn, NumberOfToken);
      WriteTableId = NewLogTable(&FingerprintVerificationInfo);
    }
  }

  return WriteTableId;
}

uint16_t WriteFaceVerificationLog(const void *pUserTokenIn, uint8_t NumberOfToken, const uint8_t Status)
{
  uint16_t WriteTableId = 0;
  LogDataSheet_t FaceVerificationLogInfo = {0};
  uint32_t NowTimestamp = MemoryGetTimestamp();

  if (pUserTokenIn != NULL)
  {
    if ((NumberOfToken > 0) && (NumberOfToken <= LOG_DATA_PACKET_LENGTH))
    {
      memset(&FaceVerificationLogInfo, 0, sizeof(LogDataSheet_t));

      FaceVerificationLogInfo.AttachParam = Status;
      FaceVerificationLogInfo.EventType = LOG_FACE_SCANF;
      FaceVerificationLogInfo.PushStatus = LOG_CACHE_TO_RETRIEVE;
      FaceVerificationLogInfo.Time[0] = (uint8_t)((NowTimestamp & 0xFF000000) >> 24);
      FaceVerificationLogInfo.Time[1] = (uint8_t)((NowTimestamp & 0x00FF0000) >> 16);
      FaceVerificationLogInfo.Time[2] = (uint8_t)((NowTimestamp & 0x0000FF00) >> 8);
      FaceVerificationLogInfo.Time[3] = (uint8_t)(NowTimestamp & 0x000000FF);
      memcpy(FaceVerificationLogInfo.DataPacket, pUserTokenIn, NumberOfToken);
      WriteTableId = NewLogTable(&FaceVerificationLogInfo);
    }
  }

  return WriteTableId;
}

uint16_t WriteCommandUnlockExecuteResultLog(const void *pDataIn, const uint8_t DataSize, const uint8_t Status)
{
  uint16_t WriteTableId = 0;
  LogDataSheet_t BlutoothOpenDoorLogInfo = {0};
  uint32_t NowTimestamp = MemoryGetTimestamp();

  if (pDataIn != NULL)
  {
    if ((DataSize != 0) && (DataSize <= LOG_DATA_PACKET_LENGTH))
    {
      memset(&BlutoothOpenDoorLogInfo, 0, sizeof(LogDataSheet_t));

      BlutoothOpenDoorLogInfo.AttachParam = Status;
      BlutoothOpenDoorLogInfo.EventType = LOG_COMMAND_OPEN_DOOR;
      BlutoothOpenDoorLogInfo.PushStatus = LOG_CACHE_TO_RETRIEVE;
      BlutoothOpenDoorLogInfo.Time[0] = (uint8_t)((NowTimestamp & 0xFF000000) >> 24);
      BlutoothOpenDoorLogInfo.Time[1] = (uint8_t)((NowTimestamp & 0x00FF0000) >> 16);
      BlutoothOpenDoorLogInfo.Time[2] = (uint8_t)((NowTimestamp & 0x0000FF00) >> 8);
      BlutoothOpenDoorLogInfo.Time[3] = (uint8_t)(NowTimestamp & 0x000000FF);
      memcpy(BlutoothOpenDoorLogInfo.DataPacket, pDataIn, DataSize);
      WriteTableId = NewLogTable(&BlutoothOpenDoorLogInfo);
    }
  }

  return WriteTableId;
}

uint16_t WriteAddNewCardholderLog(const uint8_t KeyType, const void *pKeyValueIn, const uint8_t NumberOfKey)
{
  uint16_t WriteTableId = 0;
  LogDataSheet_t AddNewCardholderLogInfo = {0};
  uint32_t NowTimestamp = MemoryGetTimestamp();

  if (NumberOfKey <= LOG_DATA_PACKET_LENGTH)
  {
    memset(&AddNewCardholderLogInfo, 0, sizeof(LogDataSheet_t));

    AddNewCardholderLogInfo.AttachParam = KeyType;
    AddNewCardholderLogInfo.EventType = LOG_NEW_CARDHOLDER;
    AddNewCardholderLogInfo.PushStatus = LOG_CACHE_TO_RETRIEVE;
    AddNewCardholderLogInfo.Time[0] = (uint8_t)((NowTimestamp & 0xFF000000) >> 24);
    AddNewCardholderLogInfo.Time[1] = (uint8_t)((NowTimestamp & 0x00FF0000) >> 16);
    AddNewCardholderLogInfo.Time[2] = (uint8_t)((NowTimestamp & 0x0000FF00) >> 8);
    AddNewCardholderLogInfo.Time[3] = (uint8_t)(NowTimestamp & 0x000000FF);
    if ((pKeyValueIn != NULL) && (NumberOfKey != 0))
    {
      memcpy(AddNewCardholderLogInfo.DataPacket, pKeyValueIn, NumberOfKey);
    }

    WriteTableId = NewLogTable(&AddNewCardholderLogInfo);
  }

  return WriteTableId;
}

uint16_t WriteChangeTheCardholderLog(const uint8_t KeyType, const void *pKeyValueIn, const uint8_t NumberOfKey)
{
  uint16_t WriteTableId = 0;
  LogDataSheet_t ChangeTheCardholderLogInfo = {0};
  uint32_t NowTimestamp = MemoryGetTimestamp();

  if (NumberOfKey <= LOG_DATA_PACKET_LENGTH)
  {
    memset(&ChangeTheCardholderLogInfo, 0, sizeof(LogDataSheet_t));

    ChangeTheCardholderLogInfo.AttachParam = KeyType;
    ChangeTheCardholderLogInfo.EventType = LOG_CHANGE_CARDHOLDER;
    ChangeTheCardholderLogInfo.PushStatus = LOG_CACHE_TO_RETRIEVE;
    ChangeTheCardholderLogInfo.Time[0] = (uint8_t)((NowTimestamp & 0xFF000000) >> 24);
    ChangeTheCardholderLogInfo.Time[1] = (uint8_t)((NowTimestamp & 0x00FF0000) >> 16);
    ChangeTheCardholderLogInfo.Time[2] = (uint8_t)((NowTimestamp & 0x0000FF00) >> 8);
    ChangeTheCardholderLogInfo.Time[3] = (uint8_t)(NowTimestamp & 0x000000FF);
    if ((pKeyValueIn != NULL) && (NumberOfKey != 0))
    {
      memcpy(ChangeTheCardholderLogInfo.DataPacket, pKeyValueIn, NumberOfKey);
    }

    WriteTableId = NewLogTable(&ChangeTheCardholderLogInfo);
  }

  return WriteTableId;
}

uint16_t WriteDeleteTheCardholderLog(const uint8_t KeyType, const void *pKeyValueIn, const uint8_t NumberOfKey)
{
  uint16_t WriteTableId = 0;
  LogDataSheet_t DeleteTheCardholderLogInfo = {0};
  uint32_t NowTimestamp = MemoryGetTimestamp();

  if (NumberOfKey <= LOG_DATA_PACKET_LENGTH)
  {
    memset(&DeleteTheCardholderLogInfo, 0, sizeof(LogDataSheet_t));

    DeleteTheCardholderLogInfo.AttachParam = KeyType;
    DeleteTheCardholderLogInfo.EventType = LOG_DELETE_CARDHOLDER;
    DeleteTheCardholderLogInfo.PushStatus = LOG_CACHE_TO_RETRIEVE;
    DeleteTheCardholderLogInfo.Time[0] = (uint8_t)((NowTimestamp & 0xFF000000) >> 24);
    DeleteTheCardholderLogInfo.Time[1] = (uint8_t)((NowTimestamp & 0x00FF0000) >> 16);
    DeleteTheCardholderLogInfo.Time[2] = (uint8_t)((NowTimestamp & 0x0000FF00) >> 8);
    DeleteTheCardholderLogInfo.Time[3] = (uint8_t)(NowTimestamp & 0x000000FF);
    if ((pKeyValueIn != NULL) && (NumberOfKey != 0))
    {
      memcpy(DeleteTheCardholderLogInfo.DataPacket, pKeyValueIn, NumberOfKey);
    }

    WriteTableId = NewLogTable(&DeleteTheCardholderLogInfo);
  }

  return WriteTableId;
}

uint16_t WriteAntiSkidAlarmLog(bool Status)
{
  uint16_t WriteTableId = 0;
  LogDataSheet_t AntiSkidAlarmLogInfo = {0};
  uint32_t NowTimestamp = MemoryGetTimestamp();

  memset(&AntiSkidAlarmLogInfo, 0, sizeof(LogDataSheet_t));

  AntiSkidAlarmLogInfo.AttachParam = Status;
  AntiSkidAlarmLogInfo.EventType = LOG_ANTI_SKID_ALARM;
  AntiSkidAlarmLogInfo.PushStatus = LOG_CACHE_TO_RETRIEVE;
  AntiSkidAlarmLogInfo.Time[0] = (uint8_t)((NowTimestamp & 0xFF000000) >> 24);
  AntiSkidAlarmLogInfo.Time[1] = (uint8_t)((NowTimestamp & 0x00FF0000) >> 16);
  AntiSkidAlarmLogInfo.Time[2] = (uint8_t)((NowTimestamp & 0x0000FF00) >> 8);
  AntiSkidAlarmLogInfo.Time[3] = (uint8_t)(NowTimestamp & 0x000000FF);
  WriteTableId = NewLogTable(&AntiSkidAlarmLogInfo);

  return WriteTableId;
}

uint16_t WriteFalseLookAlarmLog(bool Status)
{
  uint16_t WriteTableId = 0;
  LogDataSheet_t FalseLookLogInfo = {0};
  uint32_t NowTimestamp = MemoryGetTimestamp();

  memset(&FalseLookLogInfo, 0, sizeof(LogDataSheet_t));

  FalseLookLogInfo.AttachParam = Status;
  FalseLookLogInfo.EventType = LOG_FALSE_LOCK_ALARM;
  FalseLookLogInfo.PushStatus = LOG_CACHE_TO_RETRIEVE;
  FalseLookLogInfo.Time[0] = (uint8_t)((NowTimestamp & 0xFF000000) >> 24);
  FalseLookLogInfo.Time[1] = (uint8_t)((NowTimestamp & 0x00FF0000) >> 16);
  FalseLookLogInfo.Time[2] = (uint8_t)((NowTimestamp & 0x0000FF00) >> 8);
  FalseLookLogInfo.Time[3] = (uint8_t)(NowTimestamp & 0x000000FF);
  WriteTableId = NewLogTable(&FalseLookLogInfo);

  return WriteTableId;
}

uint16_t WriteDoubleLookAlarmLog(bool Status)
{
  uint16_t WriteTableId = 0;
  LogDataSheet_t DoubleLookAlarmLogInfo = {0};
  uint32_t NowTimestamp = MemoryGetTimestamp();

  memset(&DoubleLookAlarmLogInfo, 0, sizeof(LogDataSheet_t));

  DoubleLookAlarmLogInfo.AttachParam = Status;
  DoubleLookAlarmLogInfo.EventType = LOG_DOUBLE_LOCK_ALARM;
  DoubleLookAlarmLogInfo.PushStatus = LOG_CACHE_TO_RETRIEVE;
  DoubleLookAlarmLogInfo.Time[0] = (uint8_t)((NowTimestamp & 0xFF000000) >> 24);
  DoubleLookAlarmLogInfo.Time[1] = (uint8_t)((NowTimestamp & 0x00FF0000) >> 16);
  DoubleLookAlarmLogInfo.Time[2] = (uint8_t)((NowTimestamp & 0x0000FF00) >> 8);
  DoubleLookAlarmLogInfo.Time[3] = (uint8_t)(NowTimestamp & 0x000000FF);
  WriteTableId = NewLogTable(&DoubleLookAlarmLogInfo);
}

uint16_t WriteDoorContactAlarmLog(bool Status)
{
  uint16_t WriteTableId = 0;
  LogDataSheet_t DoorContactAlarmLogInfo = {0};
  uint32_t NowTimestamp = MemoryGetTimestamp();

  memset(&DoorContactAlarmLogInfo, 0, sizeof(LogDataSheet_t));

  DoorContactAlarmLogInfo.AttachParam = Status;
  DoorContactAlarmLogInfo.EventType = LOG_DOOR_CONTACT_ALRAM;
  DoorContactAlarmLogInfo.PushStatus = LOG_CACHE_TO_RETRIEVE;
  DoorContactAlarmLogInfo.Time[0] = (uint8_t)((NowTimestamp & 0xFF000000) >> 24);
  DoorContactAlarmLogInfo.Time[1] = (uint8_t)((NowTimestamp & 0x00FF0000) >> 16);
  DoorContactAlarmLogInfo.Time[2] = (uint8_t)((NowTimestamp & 0x0000FF00) >> 8);
  DoorContactAlarmLogInfo.Time[3] = (uint8_t)(NowTimestamp & 0x000000FF);
  WriteTableId = NewLogTable(&DoorContactAlarmLogInfo);

  return WriteTableId;
}

uint16_t WriteKeyUnlockLog(void)
{
  uint16_t WriteTableId = 0;
  LogDataSheet_t KeyUnlockLogInfo = {0};
  uint32_t NowTimestamp = MemoryGetTimestamp();

  memset(&KeyUnlockLogInfo, 0, sizeof(LogDataSheet_t));

  KeyUnlockLogInfo.EventType = LOG_UNLOCK_WITH_KEY;
  KeyUnlockLogInfo.PushStatus = LOG_CACHE_TO_RETRIEVE;
  KeyUnlockLogInfo.Time[0] = (uint8_t)((NowTimestamp & 0xFF000000) >> 24);
  KeyUnlockLogInfo.Time[1] = (uint8_t)((NowTimestamp & 0x00FF0000) >> 16);
  KeyUnlockLogInfo.Time[2] = (uint8_t)((NowTimestamp & 0x0000FF00) >> 8);
  KeyUnlockLogInfo.Time[3] = (uint8_t)(NowTimestamp & 0x000000FF);
  WriteTableId = NewLogTable(&KeyUnlockLogInfo);

  return WriteTableId;
}

uint16_t WriteNormalOpenLog(bool Status)
{
  uint16_t WriteTableId = 0;
  LogDataSheet_t NormalOpenLogInfo = {0};
  uint32_t NowTimestamp = MemoryGetTimestamp();

  memset(&NormalOpenLogInfo, 0, sizeof(LogDataSheet_t));

  NormalOpenLogInfo.AttachParam = Status;
  NormalOpenLogInfo.EventType = LOG_NORMAL_OPEN;
  NormalOpenLogInfo.PushStatus = LOG_CACHE_TO_RETRIEVE;
  NormalOpenLogInfo.Time[0] = (uint8_t)((NowTimestamp & 0xFF000000) >> 24);
  NormalOpenLogInfo.Time[1] = (uint8_t)((NowTimestamp & 0x00FF0000) >> 16);
  NormalOpenLogInfo.Time[2] = (uint8_t)((NowTimestamp & 0x0000FF00) >> 8);
  NormalOpenLogInfo.Time[3] = (uint8_t)(NowTimestamp & 0x000000FF);
  WriteTableId = NewLogTable(&NormalOpenLogInfo);

  return WriteTableId;
}

uint16_t WriteFirmwareUpgradeLog(void)
{
  uint16_t WriteTableId = 0;
  LogDataSheet_t FirmwareUpgradeLogInfo = {0};
  uint32_t NowTimestamp = MemoryGetTimestamp();

  memset(&FirmwareUpgradeLogInfo, 0, sizeof(LogDataSheet_t));

  FirmwareUpgradeLogInfo.AttachParam = false;
  FirmwareUpgradeLogInfo.EventType = LOG_FIRMWARE_UPGRADE;
  FirmwareUpgradeLogInfo.PushStatus = LOG_CACHE_TO_RETRIEVE;
  FirmwareUpgradeLogInfo.Time[0] = (uint8_t)((NowTimestamp & 0xFF000000) >> 24);
  FirmwareUpgradeLogInfo.Time[1] = (uint8_t)((NowTimestamp & 0x00FF0000) >> 16);
  FirmwareUpgradeLogInfo.Time[2] = (uint8_t)((NowTimestamp & 0x0000FF00) >> 8);
  FirmwareUpgradeLogInfo.Time[3] = (uint8_t)(NowTimestamp & 0x000000FF);
  WriteTableId = NewLogTable(&FirmwareUpgradeLogInfo);

  return WriteTableId;
}

uint16_t WriteDeviceStartupLog(void)
{
  uint16_t WriteTableId = 0;
  LogDataSheet_t DeviceRebootLogInfo = {0};
  uint32_t NowTimestamp = MemoryGetTimestamp();

  memset(&DeviceRebootLogInfo, 0, sizeof(LogDataSheet_t));

  DeviceRebootLogInfo.AttachParam = false;
  DeviceRebootLogInfo.EventType = LOG_DEVICE_STARTUP;
  DeviceRebootLogInfo.PushStatus = LOG_CACHE_TO_RETRIEVE;
  DeviceRebootLogInfo.Time[0] = (uint8_t)((NowTimestamp & 0xFF000000) >> 24);
  DeviceRebootLogInfo.Time[1] = (uint8_t)((NowTimestamp & 0x00FF0000) >> 16);
  DeviceRebootLogInfo.Time[2] = (uint8_t)((NowTimestamp & 0x0000FF00) >> 8);
  DeviceRebootLogInfo.Time[3] = (uint8_t)(NowTimestamp & 0x000000FF);
  WriteTableId = NewLogTable(&DeviceRebootLogInfo);

  return WriteTableId;
}

void InitialisationLogFile(void)
{
  FlashDeleteLogFile();

  LogFileAttribute_t LogFileAttribute = {0};
  memset(&LogFileAttribute, 0, sizeof(LogFileAttribute_t));
  UpdateLogFileAttribute(&LogFileAttribute);
}

bool GetWhetherThereAreLogsToBePushed(void)
{
  for (uint16_t LogId = 0; LogId < LOG_LIMIT; LogId++)
  {
    LogDataSheet_t LogDataSheet = {0};

    GetTheLogTableForTheCorrespondingCode(LogId, &LogDataSheet);
    if (LogDataSheet.PushStatus == LOG_CACHE_TO_RETRIEVE)
      return true;
  }

  return false;
}

uint16_t GetLogStackDepth(void)
{
  LogFileAttribute_t LogFileAttribute = {0};

  GetLogFileAttribute(&LogFileAttribute);
  if (LogFileAttribute.Quantity > LOG_LIMIT)
  {
    LogFileAttribute.Quantity = LOG_LIMIT;
  }

  return LogFileAttribute.Quantity;
}

void UpdateLogFilePushStatus(uint16_t LogId)
{
  LogDataSheet_t LocalLogDataSheet = {0};

  GetLogFileInformationForTheTargetCode(LogId, &LocalLogDataSheet);
  if (LocalLogDataSheet.PushStatus == LOG_CACHE_TO_RETRIEVE)
  {
    LocalLogDataSheet.PushStatus = LOG_ALREADY_PUSHED;
    UpdateTheLogTableForTheCorrespondingCode(LogId, &LocalLogDataSheet);
  }
}

bool GetLogCodesToBePushed(LogDataSheet_t *pLogDataSheetOut)
{
  if (pLogDataSheetOut != NULL)
  {
    for (uint16_t LogId = 0; LogId < LOG_LIMIT; LogId++)
    {
      LogDataSheet_t LogDataSheet = {0};

      GetTheLogTableForTheCorrespondingCode(LogId, &LogDataSheet);
      if (LogDataSheet.PushStatus == LOG_CACHE_TO_RETRIEVE)
      {
        memcpy(pLogDataSheetOut, &LogDataSheet, sizeof(LogDataSheet_t));
        UpdateLogFilePushStatus(LogId);

        return true;
      }
    }
  }

  return false;
}

void GetLogFileInformationForTheTargetCode(uint16_t TargetTableId, LogDataSheet_t *pLogFileSheetOut)
{
  GetTheLogTableForTheCorrespondingCode(TargetTableId, pLogFileSheetOut);
}
